<?php
/**
 * 数字人Service
 */

declare (strict_types=1);

namespace app\api\service;

use app\common\model\DidImage;
use app\common\model\DidTalk;
use app\common\model\UserDigitalHuman;
use app\api\exception\ApiServiceException;
use app\common\model\VoiceLab;
use app\common\service\DidService;
use think\db\exception\{DbException, ModelNotFoundException, DataNotFoundException};
use think\facade\Filesystem;
use think\facade\Request;
use think\db\Query;

class UserDigitalHumanService extends ApiBaseService
{
    protected UserDigitalHuman $model;

    public function __construct()
    {
        $this->model = new UserDigitalHuman();
    }

    /**
     * 列表
     * @param $param
     * @param $page
     * @param $limit
     * @return array
     * @throws ApiServiceException
     */
    public function getList($param, $page, $limit): array
    {
        try {
            $field = 'id,user_id,create_status,status,create_time';
            $data  = $this->model
                ->scope('ApiWhere', $param)
                ->page($page, $limit)
                ->field($field)
                ->select()
                ->toArray();
        } catch (DataNotFoundException | ModelNotFoundException $e) {
            $data = [];
        } catch (DbException $e) {
            throw new ApiServiceException('查询列表失败，信息' . $e->getMessage());
        }

        return $data;
    }
    
    /**
     * 添加
     * @param $param
     * @return UserDigitalHuman
     */
    public function createData($param): UserDigitalHuman
    {
        $result = $this->model::create($param);
        return $result;
    }
    
    /**
     * 数据详情
     * @param array $param
     * @return array
     * @throws ApiServiceException
     */
    public function getDataInfo($param): array
    {
        $data = $this->model
            ->where('id', '=', $param['id'])
            ->where('user_id', '=', $param['user_id'])
            ->findOrEmpty();
        if ($data->isEmpty()) {
            throw new ApiServiceException('数据不存在');
        }
        if ($data->create_status == UserDigitalHuman::CREATE_STATUS[2]){

            $talk = DidTalk::where('user_dh_id','=',$data->id)->findOrEmpty();
            if (!$talk->isEmpty() && empty($talk->did_status)){
                $service = new DidService();
                $data->talk = $service->getTalkById($talk->id);
            }else{
                $data->talk = $talk->toArray();
            }
            $video_url = '/uploads/user/video/'.pathinfo($data->talk['result_url'])['filename'].'.mp4';
            $file = app()->getRootPath().'public'.$video_url;
            if (!file_exists($file)){
                $content = file_get_contents($data->talk['result_url']);
                if ($content !== false){
                    file_put_contents($file,$content);
                }
            }
            $data->video_url = $video_url;
        }

        return $data->toArray();
    }

    public function saveData(int $id,array $param): array{

        $image = Request::file('image');
        if (empty($image) || empty($image->getOriginalName())){
            throw new ApiServiceException('参数错误，上传图片不能为空。');
        }
        //文件验证
        $config = config('filesystem.disks.public');

        validate(['image' => $config['validate']['image']])->check(['image'=>$image]);

        $voices = Request::file('voices');
        if (empty($voices)){
            throw new ApiServiceException('参数错误，上传音频文件不能为空。');
        }
        validate(['mp3' => $config['validate']['mp3']])->check(['mp3'=>$voices]);
        if (empty($id)){
            $data = $this->model->where('user_id', '=', $param['user_id'])->findOrEmpty();
        }else{
            $data = $this->model ->where('id', '=', $id)->findOrEmpty();
        }

        if ($data->isEmpty()) {
            $result = $this->createData($param);
            $data->id = $result->id;
        }else{
            $param['create_status'] = UserDigitalHuman::CREATE_STATUS[0];
            $result = $data->save($param);
        }

        if (!$result) {
            throw new ApiServiceException('保存数字人信息失败，请联系技术人员。');
        }
        $where_data = ['user_dh_id'=>$data->id,'user_id'=>$param['user_id']];
        DidImage::destroy(function(Query $query)use ($where_data){
            $query->where($where_data);
        });
        VoiceLab::destroy(function(Query $query)use ($where_data){
            $query->where($where_data);
        });

        $name = Filesystem::putFile('user/images', $image);
        $img_url = $config['url'] . '/' . $name;
        $img_url = str_replace("\\", '/', $img_url);
        $where_data['url'] = $img_url;
        DidImage::create($where_data);
        $urls = [];
        foreach ($voices as $voice){
            $name = Filesystem::putFile('user/voice', $voice);
            $voice_url = $config['url'] . '/' . $name;
            $voice_url = str_replace("\\", '/', $voice_url);
            $urls[] = $voice_url;
        }
        $where_data['url'] = json_encode($urls);
        VoiceLab::create($where_data);

        return $data->toArray();
    }
    
    /**
     * 修改
     * @param $id
     * @param $param
     * @return bool
     * @throws ApiServiceException
     */
    public function updateData($id, $param): bool
    {
        $data = $this->model->where('id', '=', $id)->findOrEmpty();
        if ($data->isEmpty()) {
            $this->createData($param);
            //throw new ApiServiceException('数据不存在');
        }
        $result = $data->save($param);

        if (!$result) {
            throw new ApiServiceException('更新失败');
        }

        return true;
    }
    
    /**
     * 删除
     * @param mixed $id
     * @return bool
     * @throws ApiServiceException
     */
    public function deleteData($id): bool
    {
        $result = $this->model::destroy(function ($query) use ($id) {
            $query->whereIn('id', $id);
        });

        if (!$result) {
            throw new ApiServiceException('更新失败');
        }

        return  true;
    }
    
    
    
    
}
